package br.com.gkarian.mydesk.controller.financeiro;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

import br.com.caelum.vraptor.Delete;
import br.com.caelum.vraptor.Get;
import br.com.caelum.vraptor.Post;
import br.com.caelum.vraptor.Put;
import br.com.caelum.vraptor.Resource;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.Validator;
import br.com.caelum.vraptor.validator.ValidationMessage;
import br.com.gkarian.mydesk.anotacoes.RestritoAdmin;
import br.com.gkarian.mydesk.enums.TipoConta;
import br.com.gkarian.mydesk.model.financeiro.Banco;
import br.com.gkarian.mydesk.services.financeiro.interfaces.FinanceiroServiceProxy;
import br.com.gkarian.mydesk.web.UsuarioWeb;

@Resource
@RestritoAdmin
public class BancoController {
	
	private static final Logger LOG = Logger.getLogger(BancoController.class);

	private Result result;
	private Validator validator;
	private UsuarioWeb usuarioWeb;
	private FinanceiroServiceProxy financeiroServiceProxy;
	
	public BancoController(Result result, Validator validator,
			UsuarioWeb usuarioWeb,
			FinanceiroServiceProxy financeiroServiceProxy) {
		this.result = result;
		this.validator = validator;
		this.usuarioWeb = usuarioWeb;
		this.financeiroServiceProxy = financeiroServiceProxy;
	}
	
	@Get("/financeiro/banco/cadastrar")
	public void cadastrarBanco() {
		LOG.info("Abrindo página para cadastro de Banco!");
		result.include("listTipoConta", gerarListaTipoConta());
	}

	@Post("/financeiro/banco/cadastrando")
	public void cadastrar(Banco banco) {
		LOG.info("Realizando validação de cadastro do banco");
		validator.validate(banco);
		validator.onErrorRedirectTo(this).cadastrarBanco();
		
		try {
			LOG.info("Cadastrando banco = " + banco);
			financeiroServiceProxy.cadastrarBanco(banco);
			result.redirectTo(this).cadastrarBanco();
		} catch (Exception e) {
			LOG.error("Erro ao cadastrar Banco", e);
			validator.add(new ValidationMessage("erro.inesperado", "error"));
			validator.onErrorRedirectTo(this).cadastrarBanco();
		}
	}

	@Get("/financeiro/banco/listar")
	public void listarBancos() {
		try {
			List<Banco> listaBancos = financeiroServiceProxy.listarBancos();
			result.include("listBancos", listaBancos);
		} catch (Exception e) {
			LOG.error("Erro ao ListarBancos", e);
			validator.add(new ValidationMessage("erro.inesperado", "error"));
			validator.onErrorRedirectTo(this).cadastrarBanco();
		}
	}
	
	@Delete("/financeiro/banco/{id}/remover")
	public void remover(Integer id) {
		try {
			LOG.info("Recuperando banco de ID ["+ id +"] para remoção");
			Banco banco = financeiroServiceProxy.carregarBanco(id);
			if (banco == null) {
				LOG.info("Banco de ID [" + id + "] inexistente!");
				validator.add(new ValidationMessage("banco.inexistente", "error")); //TODO: Testar!
				validator.onErrorRedirectTo(this).listarBancos();
				return;
			}
			
			LOG.info("Usuario: + " + usuarioWeb.getLogado() + " removendo Banco ID [" + banco.getId() + "]");
			financeiroServiceProxy.removerBanco(banco);
			LOG.info("Banco removido ID [" + banco.getId() + "] com Sucesso!");
			
			result.redirectTo(this).listarBancos();
		} catch (Exception e) {
			LOG.error("Erro ao remover o Banco", e);
			validator.add(new ValidationMessage("erro.inesperado", "error"));
			validator.onErrorRedirectTo(this).cadastrarBanco();
		}
	}
	
	@Get("/financeiro/banco/{id}/editar")
	public void editarBanco(Integer id) {
		try {
			LOG.info("Recuperando banco de ID ["+ id +"] para edição");
			Banco banco = financeiroServiceProxy.carregarBanco(id);
			LOG.info("Banco de ID ["+ banco.getId() +"] recuperado!");
			result.include("banco", banco);
			result.include("listTipoConta", gerarListaTipoConta());
		} catch (Exception e) {
			LOG.error("Erro ao recuperar Banco para editá-lo", e);
			validator.add(new ValidationMessage("erro.inesperado", "error"));
			validator.onErrorRedirectTo(this).listarBancos();
		}
	}
	
	@Put("/financeiro/banco/editando")
	public void editarBanco(Banco banco) {
		LOG.info("Realizando validação de edição do banco com ID [" + banco.getId() + "]");
		validator.validate(banco);
		validator.onErrorRedirectTo(this).listarBancos();
		
		try {
			LOG.info("Editando banco de ID [" + banco.getId() + "]");
			financeiroServiceProxy.atualizarBanco(banco);
			LOG.info("Banco com ID [" + banco.getId() + "] editado com Sucesso!");
			result.redirectTo(this).listarBancos();
		} catch (Exception e) {
			LOG.error("Erro ao editar o Banco", e);
			validator.add(new ValidationMessage("erro.inesperado", "error"));
			validator.onErrorRedirectTo(this).listarBancos();
		}
	}
	
	private List<String> gerarListaTipoConta() {
		List<String> listTipoConta = new ArrayList<String>();
		listTipoConta.add("Selecione");
		listTipoConta.add(TipoConta.CC.getNome());
		listTipoConta.add(TipoConta.PP.getNome());
		return listTipoConta;
	}
	
	
	
}
